package com.cj.bigfileupload.service.impl;

import com.cj.bigfileupload.common.GlobalConsts;
import com.cj.bigfileupload.common.WebUploadConfigParam;
import com.cj.bigfileupload.common.exception.BusinessException;
import com.cj.bigfileupload.common.util.FileUtil;
import com.cj.bigfileupload.controller.request.MultipartFileParam;
import com.cj.bigfileupload.service.IFileUploadService;
import com.cj.bigfileupload.service.IWebUploadService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;

/**
 * ClassName: FileUploadServiceImpl <br/>
 * Function: 文件上传service实现 <br/>
 * date: 2018/05/08 15:42 <br/>
 *
 * @author chenj
 * @version 1.0.0
 * @since JDK 1.8
 */
@Service
public class FileUploadServiceImpl implements IFileUploadService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private WebUploadConfigParam webUploadConfigParam;
    @Resource
    private IWebUploadService webUploadService;

    @Override
    public String getConfFilePathFromRedis(String md5) {
        if (StringUtils.isEmpty(md5)) {
            return null;
        }
        Object obj = stringRedisTemplate.opsForHash().get(GlobalConsts.DEPLOY_FILE_MD5_KEY, md5);
        if (obj == null) {
            return null;
        }
        return obj.toString();
    }

    @Override
    public void uploadFile(MultipartFileParam param) {
        String uploadDirPath = webUploadConfigParam.getLocationFilePath() + File.separatorChar + param.getMd5();
        boolean isUploaded = false;
        try {
            isUploaded = webUploadService.uploadFileRandomAccessFile(uploadDirPath, param);
        } catch (Exception e) {
            // 删除
            String fileName = param.getName();
            FileUtil.deleteFile(uploadDirPath + File.separatorChar + fileName + GlobalConsts.FILE_TMP_SUFFIX);
            FileUtil.deleteFile(uploadDirPath + File.separatorChar + fileName + GlobalConsts.FILE_CONF_SUFFIX);
            // 删除缓存
            deleteRedisFileMd5Key(param.getMd5());
            throw new BusinessException("error.fileupload.fail");
        }
        if (isUploaded) {
            processAfterUploadSuccess(param, uploadDirPath);
        } else {
            // 将MD5对应的conf文件放入缓存，用于断点续传
            if (!stringRedisTemplate.opsForHash().hasKey(GlobalConsts.DEPLOY_FILE_MD5_KEY, param.getMd5())) {
                stringRedisTemplate.opsForHash()
                        .put(GlobalConsts.DEPLOY_FILE_MD5_KEY, param.getMd5(),
                                uploadDirPath + File.separatorChar + param.getName() + GlobalConsts.FILE_CONF_SUFFIX);
            }
        }
    }

    /**
     * 删除缓存
     *
     * @param md5
     */
    private void deleteRedisFileMd5Key(String md5) {
        stringRedisTemplate.opsForHash().delete(GlobalConsts.DEPLOY_FILE_MD5_KEY, md5);
    }

    /**
     * 上传完成操作
     *
     * @param param
     * @param uploadDirPath
     * @return
     * @throws IOException
     */
    private void processAfterUploadSuccess(MultipartFileParam param, String uploadDirPath) {
        // 删除conf文件
        FileUtil.deleteFile(uploadDirPath + File.separatorChar + param.getName() + GlobalConsts.FILE_CONF_SUFFIX);
        // 删除缓存
        deleteRedisFileMd5Key(param.getMd5());
    }
}
